
BasePath.setByDoc(document, "/livcos.org/MindNavi/web/navi.html");

scriptSupport.addInit(function() {
	var navDoc = new NavDoc(document);
	var nav = new Navigation(navDoc);
  nav.navTo(navDoc.content.id);
  navDoc.content.id = "";
  new EventListener(document, "keydown", function(evn) {
    if (evn.keyCode == 27) { // ESC
      this.insertPanel && this.insertPanel.hide();
      this.insertPanel && this.insertPanel._disable.hide();
    }
    else if (evn.keyCode == 45) { // insert
      var a = new ShowInsertAction();
      a.perform();
      a.close();
    }
  });
});

function NavDoc(doc) {
  var tables = doc.body.getElementsByTagName("table");
  this.relLeft = tables[1];
  this.relRight = tables[2];
  this.navBox = tables[0].firstChild.firstChild.childNodes[1];
  this.content = tables[0].firstChild.childNodes[1].childNodes[0].firstChild;
  this.relLeftTmpl = this.relLeft.firstChild;
  this.relRightTmpl = this.relRight.firstChild;
  this.mainTmpl = this.navBox.lastChild;
  this.navTmpl = this.navBox.cloneNode(true);
}

NavDoc.prototype.clear = function() {
  this.relLeft = NavDoc._renew(this.relLeft);
  this.relRight = NavDoc._renew(this.relRight);
  this.navBox.innerHTML = "";
}

NavDoc._renew = function(element) {
  var e = element.ownerDocument.createElement(element.tagName);
  e.className = element.className;
  element.parentNode.replaceChild(e, element);
  return e;
}

NavDoc.prototype.draw = function(thought) {
  this.content.id = thought.id;
  this.content.innerHTML = "";
  if (thought.image)
    this.content.innerHTML += "<p><img src=\""+thought.image+"\">"+thought.image+"</img></p>";
  if (thought.link)
    this.content.innerHTML += "<p><a href=\""+thought.link+"\">"+thought.link+"</a></p>";
  var EMPTY_NOTE_MSG = "-- add note --";
  this.content.innerHTML += "<textarea>" + ((thought.note)?thought.note:EMPTY_NOTE_MSG) + "</textarea>";
  var note = this.content.lastChild;
  note._originalText = thought.note;
  if (!thought.note) {
  	note.className = "inactive";
  }
  note.onfocus = function() {
    this.className = "active";
  };
  note.onblur = function() {
  	var val = this.value;
    if (val == EMPTY_NOTE_MSG)
      val = "";
    if (val == "") {
      this.value = EMPTY_NOTE_MSG;
      this.className = "inactive";
    }
    else {
      this.className = "";
    }
    if ((val != this._originalText) || (this._originalText && (val == ""))) {
	    var a = new UpdateNoteAction(val);
	    a.perform();
	    a.close();
    }
  };
}

NavDoc._draw = function(rel, parentNode, template, left) {
	if (parentNode.firstChild) {
    var s = template.cloneNode(true);
    s.removeChild(s.firstChild);
    parentNode.appendChild(s);
	}
	var c = template.cloneNode(true);
	c.removeChild(c.childNodes[1]);
  var e = c.firstChild.childNodes[(left)?1:0].firstChild;
  e.id = rel.thgt.id + "#" + rel.id;
  e._rel = rel;
  e.innerHTML = rel.to.label;
  e.onclick = NavDoc.onClick;
  parentNode.appendChild(c);
  e = c.firstChild.childNodes[(left)?0:1];
  e.className = "";
  e.innerHTML = "&#160;";
  c._left = left;
  return c;
}

NavDoc._drawSub = function(rel, container, template) {
  var e = template.cloneNode(false);
  e.id = rel.thgt.id + "#" + rel.id;
  e._rel = rel;
  e.innerHTML = rel.to.label;
  e.onclick = NavDoc.onClick;
  var d = container.firstChild.childNodes[(container._left)?0:1];
  if (d.className != "") {
    var r = container.ownerDocument.createElement("tr");
    r.appendChild(e);
    container.appendChild(r, container.lastChild);
  }
  else {
    container.firstChild.replaceChild(e, d);
  }
  container.firstChild.childNodes[(container._left)?1:0].rowSpan = container.childNodes.length;
}

NavDoc.prototype.drawRel = function(rel) {
  if (this.relRight.childNodes.length > this.relLeft.childNodes.length)
    return NavDoc._draw(rel, this.relLeft, this.relLeftTmpl, true);
  else
    return NavDoc._draw(rel, this.relRight, this.relRightTmpl, false);
}

NavDoc.prototype.drawSubRel = function(rel, container) {
  if (container._left)
    NavDoc._drawSub(rel, container, this.relLeftTmpl.firstChild.childNodes[0]);
  else
    NavDoc._drawSub(rel, container, this.relRightTmpl.firstChild.childNodes[1]);
}

NavDoc.prototype.drawNav = function(thought, level) {
	var tmpls = this.navTmpl.childNodes;
	var idx = tmpls.length - level - 1;
	if (idx < 0)
	  idx = 0;
  var e = tmpls[idx].cloneNode(true);
  e.id = thought.id;
  e.innerHTML = thought.label;
  e.onclick = NavDoc.onClick;
  this.navBox.appendChild(e);
  if (level == 0)
    this.draw(thought);
}

NavDoc.onClick = function(evn) {
	evn = (evn)?evn:window.event;
	if ((evn.button < 2) && (evn.type == "click"))
    document._nav.navTo((this._rel)?this._rel.to:this.id);
}


function Navigation(navDoc) {
	this.doc = navDoc;
	this.doc.clear();
  this.navs = new Array();
  this.sIdx = 0;
  this.thoughts = new Object();
  this.list = new Array();
  document._nav = this;
}

/**
 * Navigate to and focus the given thought.
 * @param {Thought} thought The to navigate to. 
 * @param {boolean} [reselect] Reselect the given thought, even though it's currently selected already.
 */
Navigation.prototype.navTo = function(thought, reselect) {
  if (typeof(thought) == "string")
    thought = this.createThought({id: thought});
  if (!reselect && (this.current == thought))
    return;
  var f = -1;
  for (var i = 0; i < this.navs.length; ++i) {
    if (this.navs[i] == thought)
      f = i;
  }
  if (f < 0) {
    this.navs[this.navs.length] = thought;
  }
  this.current = thought;
  this.current.load();
}

Navigation.prototype.draw = function() {
	this.doc.clear();
  var f = -1;
  for (var i = 0; i < this.navs.length; ++i) {
    if (this.navs[i] == this.current)
      f = i;
  }
  for (var i = 0; i < this.navs.length; ++i) {
    var d = i - f;
    this.doc.drawNav(this.navs[i], (d >= 0)?d:-d);
  }
  var prev = this.navs[f - 1];
  if (this.current.rels) {
	  for (var i = 0; i < this.current.rels.length; ++i) {
	  	var rel = this.current.rels[i];
	    if (rel != prev) {
	      var e = this.doc.drawRel(rel);
	      if (rel.to.rels) {
			    for (var j = 0; j < rel.to.rels.length; ++j) {
			      var r = rel.to.rels[j];
			      if (r.to != this.current)
			        this.doc.drawSubRel(r, e);
			    }
	      }
	    }
	  }
  }
}

Navigation.prototype.createThought = function(config) {
	var t = this.thoughts[config.id];
  if (!t) {
    t = new Thought(this, config.id);
    this.thoughts[t.id] = t;
    t.init(config);
  }
  else {
    t.setRelations(config);
  }
  return t;
}


function Thought(nav, id) {
	this.nav = nav;
	this.id = id;
}

Thought.prototype.init = function(config) {
  this.label = config.label;
  this.note = config.note;
  this.link = config.link;
  delete(this.rels);
  this.setRelations(config);
}

Thought.prototype.load = function() {
  if (!this.data) {
    this.data = this;
    this.data = new Resource("thought.view?ref="+this.id, "");
    this.data._thgt = this;
    this.data.onCompleted = function() {
      eval("var d = "+this.text);
      this._thgt.init(d);
      this._thgt.nav.draw();
      this.statusLog.show("...thought loaded.");
    }
    this.data.load();
  }
  else if (this.data.hasCompleted && this.data.hasCompleted()) {
    this.nav.draw();
  }
}

Thought.prototype.setRelations = function(config) {
	if (this.rels || !config || !config.rels)
	  return;
	this.rels = config.rels;
  for (var i = 0; i < this.rels.length; ++i) {
  	var r = this.rels[i]
  	r.to = this.nav.createThought(r.to);
  	r.thgt = this;
  }
}

